<?php

namespace app\models;

use Yii;
use yii\base\Exception;
use yii\base\Model;

/**
 * 卡分配表单
 * Class CardDispatchForm
 * @package app\models
 */
class CardDispatchForm extends Model
{
    /**
     * @var string 卡来源 iccid range search
     */
    public $source;
    /**
     * @var string 多条ICCID
     */
    public $iccid_list;
    /**
     * @var string ICCID开始号码
     */
    public $iccid_start;
    /**
     * @var string ICCID结束号码
     */
    public $iccid_end;
    /**
     * @var integer 搜索接口编号
     */
    public $search_api_id;
    /**
     * @var integer 搜索运营商编号
     */
    public $search_isp_id;
    /**
     * @var string 搜索批次号
     */
    public $search_batch_no;
    /**
     * @var string 用户类型 agent user
     */
    public $user_type;
    /**
     * @var string 用户名
     */
    public $username;
    /**
     * @var Agent $agent 操作代理商
     */
    public $agent;

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            ['source', 'default', 'value' => 'iccid'],
            [['iccid_list', 'iccid_start', 'iccid_end'], 'safe'],
            [['search_api_id', 'search_isp_id'], 'integer'],
            [['source', 'user_type', 'username'], 'required'],
            ['user_type', 'default', 'value' => 'user'],
            ['search_batch_no', 'string'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'source' => '来源',
            'iccid_list' => 'ICCID列表',
            'iccid_start' => 'ICCID开始号码',
            'iccid_end' => 'ICCID结束号码',
            'search_api_id' => '搜索接口',
            'search_isp_id' => '搜索运营商',
            'search_batch_no' => '搜索批次号',
            'user_type' => '用户类型',
            'username' => '用户名',
        ];
    }

    /**
     * 分配
     * @return boolean
     */
    public function dispatch()
    {
        if (!$this->validate()) {
            return false;
        }
        if (!empty($this->agent)) {
            // 代理商分配卡，需要判断分配用户具有从属关系
            if ($this->user_type == 'user') {
                $user = User::findOne(['username' => $this->username, 'status' => User::STATUS_OK]);
                if ($user->agent_id != $this->agent->id) {
                    $this->addError('username', '没有找到用户。');
                }
            }
            if ($this->user_type == 'agent') {
                $agent = Agent::findOne(['username' => $this->username, 'status' => Agent::STATUS_OK]);
                if (!Agent::checkRelation($this->agent->id, $agent->id)) {
                    $this->addError('username', '没有找到代理商。');
                }
            }
            if ($this->hasErrors()) {
                return false;
            }
        }
        /** @var Card[] $cardList */
        $cardList = [];
        /** @var array $packageIdList 涉及到的套餐编号，需要用来检查用户是否设置此套餐价格（UserPackage） */
        if ($this->source == 'iccid') {
            // 直接填写
            $iccidList = preg_split('/\s/', $this->iccid_list, -1, PREG_SPLIT_NO_EMPTY);
            if (empty($iccidList)) {
                $this->addError('iccid_list', '没有找到任何待分配的卡。');
                return false;
            }
            foreach ($iccidList as $iccid) {
                $card = Card::findOne(['iccid' => $iccid]);
                if (empty($card)) {
                    $this->addError('iccid_list', 'ICCID【' . $iccid . '】不是有效的卡。');
                    return false;
                }
                if (!empty($this->agent) && $card->agent_id != $this->agent->id) {
                    $this->addError('iccid_list', 'ICCID【' . $card->iccid . '】不是有效的卡。');
                    return false;
                }
                if ($this->user_type == 'user' && !empty($card->uid)) {
                    $this->addError('iccid_list', 'ICCID【' . $card->iccid . '】已经有分配的用户了。');
                    return false;
                }
                if (empty($this->agent) && $this->user_type == 'agent' && !empty($card->agent_id)) {
                    $this->addError('iccid_list', 'ICCID【' . $card->iccid . '】已经有分配的代理商了。');
                    return false;
                }
                if (empty($card->package_id)) {
                    $this->addError('iccid_list', 'ICCID【' . $card->iccid . '】没有设置有效的套餐。');
                    return false;
                }
                $packageIdList[$card->package_id] = $card->package_id;
                $cardList[] = $card;
            }
        } elseif ($this->source == 'range') {
            // 起止卡号
            if (empty($this->iccid_start)) {
                $this->addError('iccid_start', 'ICCID开始号码必须填写。');
                return false;
            }
            if (empty($this->iccid_end)) {
                $this->addError('iccid_end', 'ICCID结束号码必须填写。');
                return false;
            }
            if (strlen($this->iccid_start) != strlen($this->iccid_end)) {
                $this->addError('iccid_end', 'ICCID开始号码和结束号码长度不一致。');
                return false;
            }
            // 范围内的ICCID列表
            for ($i = 0; $i < strlen($this->iccid_start); $i++) {
                if ($this->iccid_start[$i] != $this->iccid_end[$i]) {
                    $prefix = substr($this->iccid_start, 0, $i);
                    $iccidList = range(substr($this->iccid_start, $i), substr($this->iccid_end, $i));
                    $chrLen = strlen(substr($this->iccid_start, $i));
                    foreach ($iccidList as $item) {
                        $iccid = $prefix . str_pad($item, $chrLen, '0', STR_PAD_LEFT);
                        $card = Card::findOne(['iccid' => $iccid]);
                        if (empty($card)) {
                            $this->addError('iccid_list', 'ICCID【' . $iccid . '】不是有效的卡。');
                            return false;
                        }
                        if (!empty($this->agent) && $card->agent_id != $this->agent->id) {
                            $this->addError('iccid_list', 'ICCID【' . $card->iccid . '】不是有效的卡。');
                            return false;
                        }
                        if ($this->user_type == 'user' && !empty($card->uid)) {
                            $this->addError('iccid_list', 'ICCID【' . $card->iccid . '】已经有分配的用户了。');
                            return false;
                        }
                        if (empty($this->agent) && $this->user_type == 'agent' && !empty($card->agent_id)) {
                            $this->addError('iccid_list', 'ICCID【' . $card->iccid . '】已经有分配的代理商了。');
                            return false;
                        }
                        if (empty($card->package_id)) {
                            $this->addError('iccid_list', 'ICCID【' . $card->iccid . '】没有设置有效的套餐。');
                            return false;
                        }
                        $packageIdList[$card->package_id] = $card->package_id;
                        $cardList[] = $card;
                    }
                    break;
                }
            }
        } elseif ($this->source == 'search') {
            // 通过查询条件搜索
            $query = Card::find();
            $query->andFilterWhere(['api_id' => $this->search_api_id]);
            $query->andFilterWhere(['isp_id' => $this->search_isp_id]);
            $query->andFilterWhere(['batch_no' => $this->search_batch_no]);
            if (!empty($this->agent)) {
                $query->andFilterWhere(['agent_id' => $this->agent->id]);
            }
            /** @var Card $card */
            foreach ($query->each() as $card) {
                if ($this->user_type == 'user' && !empty($card->uid)) {
                    $this->addError('iccid_list', 'ICCID【' . $card->iccid . '】已经有分配的用户了。');
                    return false;
                }
                if (empty($this->agent) && $this->user_type == 'agent' && !empty($card->agent_id)) {
                    $this->addError('iccid_list', 'ICCID【' . $card->iccid . '】已经有分配的代理商了。');
                    return false;
                }
                if (empty($card->package_id)) {
                    $this->addError('iccid_list', 'ICCID【' . $card->iccid . '】没有设置有效的套餐。');
                    return false;
                }
                $packageIdList[$card->package_id] = $card->package_id;
                $cardList[] = $card;
            }
        }

        $trans = Yii::$app->db->beginTransaction();
        try {
            if ($this->user_type == 'user') {
                $user = User::findOne(['username' => $this->username, 'status' => User::STATUS_OK]);
                foreach ($packageIdList as $packageId) {
                    if (!UserPackage::find()->andWhere(['uid' => $user->id, 'package_id' => $packageId])->exists()) {
                        $package = Package::findOne(['id' => $packageId]);
                        $this->addError('username', '此用户没有设置套餐【' . $package->name . '】的价格。');
                        throw new Exception();
                    }
                }
                foreach ($cardList as $card) {
                    $card->uid = $user->id;
                    $card->save(false);
                }
            } elseif ($this->user_type == 'agent') {
                $agent = Agent::findOne(['username' => $this->username, 'status' => Agent::STATUS_OK]);
                foreach ($packageIdList as $packageId) {
                    if (!AgentPackage::find()->andWhere(['agent_id' => $agent->id, 'package_id' => $packageId])->exists()) {
                        $package = Package::findOne(['id' => $packageId]);
                        $this->addError('username', '此代理商没有设置套餐【' . $package->name . '】的价格。');
                        throw new Exception();
                    }
                }
                foreach ($cardList as $card) {
                    $card->agent_id = $agent->id;
                    $card->save(false);
                }
            }
            $trans->commit();
            return true;
        } catch (Exception $e) {
            try {
                $trans->rollBack();
            } catch (Exception $_) {
            }
        }
        return false;
    }
}
